﻿using System;
using System.Threading;

namespace UtilZ.Dotnet.Ex.Model
{


#pragma warning disable 8500 // address / sizeof of managed types

    /************************************************************************************************
     * realloc函数说明:
     * void* realloc(void* memblock, size_t size);
     * 
     * 参数:
     * 1.memblock: 指向之前已分配内存块的指针。
     *             如果 memblock 为 NULL，则 realloc 与 malloc 的行为相同，并分配一个 size 字节的新块。 
     *             如果 memblock 不是 NULL，则它应该是之前对 calloc、 malloc或 realloc的调用返回的指针。
     * 2.size: 新大小（字节）。
     *             块的内容不随其新旧大小而更改，尽管新块可以在不同的位置。 由于新块可以位于新的内存位置中，
     *             因此不一定由 realloc 返回的指针是通过 参数传递的 memblock 指针。 realloc 如果存在缓冲区增长，则不会为零新分配的内存。
     *             
     * 注：如果内存分配失败或请求的内存量超过 _HEAP_MAXREQ，则 realloc 将 errno 设置为 ENOMEM(该常量定义在类ErrnoConstant中)。 
     *     有关此错误代码和其他错误代码的信息，请参阅 errno、_doserrno、_sys_errlist 和 _sys_nerr。
     * #ifdef _WIN64
     *      #define _HEAP_MAXREQ 0xFFFFFFFFFFFFFFE0      //十进制为: 18446744073709552000 -> 17179869184 GB
     * #else
     *      #define _HEAP_MAXREQ 0xFFFFFFE0              //十进制为: 4294967264 -> 4095.999 MB
     * #endif
     * 
     * 
     * 返回值:
     * realloc 将返回指向重新分配的（并且可能已移动的）内存块的 void 指针。
     * 如果没有足够的可用内存将块扩展到给定的大小，则原始块保持不变，并 NULL 返回。
     * 如果 size 为零，则释放由 memblock 指向的块；返回值为 NULL，而 memblock 仍指向已释放的块。
     * 返回值将指向适当对齐任何类型的对象的存储的存储空间。 若要获取指向类型而非 void 的指针，请在返回值中使用类型转换。
     * 
     * 
     * 
     * 场景一、将分配的内存减少,只有一种情况：
     * 1）realloc仅仅是改变索引的信息。
     * 
     * 场景二、将分配的内存扩大，则有以下情况：
     * 1）如果当前内存段后面有需要的内存空间，则直接扩展这段内存空间，realloc()将返回原指针。
     * 
     * 2）如果当前内存段后面的空闲字节不够，那么就使用堆中的第一个能够满足这一要求的内存块，
     *    将目前的数据复制到新的位置，并将原来的数据块释放掉，返回新的内存块位置。
     *    
     * 3）如果申请失败，将返回NULL，此时，原来的指针仍然有效。
     * 
     * 注意：如果调用成功，不管当前内存段后面的空闲空间是否满足要求，都会释放掉原来的指针，
     *       重新返回一个指针，虽然返回的指针有可能和原来的指针一样，即不能再次释放掉原来的指针。
     ************************************************************************************************/


    /// <summary>
    /// 非托管内存指针基类
    /// </summary>
    unsafe public abstract class UnmanagedMemoryPointerAbs : IUnmanagedMemoryPointer
    {
        /// <summary>
        /// 非托管内存扩展事件
        /// </summary>
        public static event EventHandler<UnmanagedMemoryExtendedArgs> OnUnmanagedMemoryExtended;

        /// <summary>
        /// 内存标识ID索引
        /// </summary>
        private static long _idIndex = 1;

        private static long _total = 0;
        /// <summary>
        /// 获取当前已申请且未释放内存块数
        /// </summary>
        public static long Total
        {
            get { return Interlocked.Read(ref _total); }
        }

        private static long _totalBytes = 0L;
        /// <summary>
        /// 获取申请的总字节数
        /// </summary>
        public static long TotalBytes
        {
            get { return Interlocked.Read(ref _totalBytes); }
        }


        private readonly long _id;
        /// <summary>
        /// 内存标识ID
        /// </summary>
        public long ID
        {
            get { return this._id; }
        }

        /// <summary>
        /// 内存类型
        /// </summary>
        private readonly UnmanagedMemoryType _memoryType;
        /// <summary>
        /// 内存类型
        /// </summary>
        public UnmanagedMemoryType MemoryType
        {
            get { return this._memoryType; }
        }

        private UnmanagedMemoryAdjustMode _adjustMode = UnmanagedMemoryAdjustMode.Limit;
        /// <summary>
        /// 非托管内存调整模式
        /// </summary>
        public UnmanagedMemoryAdjustMode AdjustMode
        {
            get { return this._adjustMode; }
            set { this._adjustMode = value; }
        }

        /// <summary>
        /// 单个元素大小
        /// </summary>
        protected readonly int _elementSize;
        /// <summary>
        /// 单个元素大小
        /// </summary>
        public int ElementSize
        {
            get { return this._elementSize; }
        }





        /// <summary>
        /// 指针对应类型结构的元素最大个数
        /// </summary>
        protected int _capacity = 0;
        /// <summary>
        /// 指针对应类型结构的元素最大个数
        /// </summary>
        public int Capacity
        {
            get { return _capacity; }
        }

        /// <summary>
        /// 指针对应类型结构的元素最大个数
        /// </summary>
        protected long _longCapacity = 0L;
        /// <summary>
        /// 指针对应类型结构的元素最大个数
        /// </summary>
        public long LongCapacity
        {
            get { return _longCapacity; }
        }






        /// <summary>
        /// 有效数据元素个数
        /// </summary>
        protected int _length = 0;
        /// <summary>
        /// 有效数据元素个数
        /// </summary>
        public int Length
        {
            get { return this._length; }
            set
            {
                this._length = value;
                this._longLength = value;
            }
        }


        /// <summary>
        /// 有效数据元素个数
        /// </summary>
        protected long _longLength = 0L;
        /// <summary>
        /// 有效数据元素个数
        /// </summary>
        public long LongLength
        {
            get { return this._longLength; }
            set
            {
                if (value > int.MaxValue)
                {
                    this._length = int.MaxValue;
                }
                else
                {
                    this._length = (int)value;
                }
                this._longLength = value;
            }
        }

        private int _maxAutoCount = 1000;
        /// <summary>
        /// 获取或设置自动调整内存模式时,最大连续减小内存次数(默认1000),当达到此值时就减小次内存一次
        /// </summary>
        public int MaxAutoCount
        {
            get { return this._maxAutoCount; }
            set { this._maxAutoCount = value; }
        }

        private string _error = null;
        /// <summary>
        /// 获取检查内存失败时的错误信息
        /// </summary>
        public string Error
        {
            get { return this._error; }
        }


        /// <summary>
        /// 数据
        /// </summary>
        public object Tag { get; set; }


        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="elementSize">元素大小</param>
        /// <param name="elementCount">元素个数</param>
        /// <param name="memoryType">非托管内存类型</param>
        public UnmanagedMemoryPointerAbs(int elementSize, long elementCount, UnmanagedMemoryType memoryType)
        {
            this._id = Interlocked.Increment(ref _idIndex);
            Interlocked.Increment(ref _total);

            this._elementSize = elementSize;
            this._memoryType = memoryType;

            if (elementCount > 0)
            {
                if (memoryType == UnmanagedMemoryType.Revisable)
                {
                    this.CheckSetLength(elementCount);
                }
                else
                {
                    if (elementCount > int.MaxValue)
                    {
                        this._length = int.MaxValue;
                        this._capacity = int.MaxValue;
                    }
                    else
                    {
                        this._length = (int)elementCount;
                        this._capacity = (int)elementCount;
                    }
                    this._longLength = elementCount;
                    this._longCapacity = elementCount;
                }
            }

        }





        /// <summary>
        /// 检查内存大小是否足够.
        /// 检查过程中根据内存调整模式对内存进行调整,不调整或调整成功正常则设置数据长度为调整长度,操作成功失败抛出异常
        /// </summary>
        /// <param name="elementCount">需要的元素个数</param>
        public void CheckSetLength(int elementCount)
        {
            if (elementCount < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(elementCount), $"元数个数不能小于0,值\"{elementCount}\"无效.");
            }

            if (elementCount > this._capacity)
            {
                if (!this.PrimitiveCheck(elementCount))
                {
                    throw new AccessViolationException($"内存指针元素个数从{this._longCapacity}-{elementCount}申请或调整内存失败,错误信息:{this._error}");
                }
            }

            this._length = elementCount;
            this._longLength = elementCount;
        }

        /// <summary>
        /// 检查内存大小是否足够.
        /// 检查过程中根据内存调整模式对内存进行调整,不调整或调整成功正常则设置数据长度为调整长度,操作成功失败抛出异常
        /// </summary>
        /// <param name="elementCount">需要的元素个数</param>
        public void CheckSetLength(long elementCount)
        {
            if (elementCount < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(elementCount), $"元数个数不能小于0,值\"{elementCount}\"无效.");
            }

            if (elementCount > this._longCapacity)
            {
                if (!this.PrimitiveCheck(elementCount))
                {
                    throw new AccessViolationException($"内存指针元素个数从{this._longCapacity}-{elementCount}申请或调整内存失败,错误信息:{this._error}");
                }
            }

            if (elementCount > int.MaxValue)
            {
                this._length = int.MaxValue;
            }
            else
            {
                this._length = (int)elementCount;
            }

            this._longLength = elementCount;
        }

        /// <summary>
        /// 尝试检查内存大小是否足够.如果不够则内存进行调整,不调整或调整成功正常则设置数据长度为调整长度,操作成功返回true,失败返回false
        /// </summary>
        /// <param name="elementCount">需要的元素个数</param>
        /// <returns>成功返回true,失败返回false</returns>
        public bool TryCheckSetLength(int elementCount)
        {
            if (elementCount < 0)
            {
                return false;
            }

            if (elementCount > this._capacity)
            {
                if (!this.PrimitiveCheck(elementCount))
                {
                    return false;
                }
            }

            this._length = elementCount;
            this._longLength = elementCount;
            return true;
        }

        /// <summary>
        /// 尝试检查内存大小是否足够.如果不够则内存进行调整,不调整或调整成功正常则设置数据长度为调整长度,操作成功返回true,失败返回false
        /// </summary>
        /// <param name="elementCount">需要的元素个数</param>
        /// <returns>成功返回true,失败返回false</returns>
        public bool TryCheckSetLength(long elementCount)
        {
            if (elementCount < 0)
            {
                return false;
            }

            if (elementCount > this._longCapacity)
            {
                if (!this.PrimitiveCheck(elementCount))
                {
                    return false;
                }
            }

            if (elementCount > int.MaxValue)
            {
                this._length = int.MaxValue;
            }
            else
            {
                this._length = (int)elementCount;
            }

            this._longLength = elementCount;
            return true;
        }




        /// <summary>
        /// 检查内存大小是否足够.检查过程中根据内存调整模式对内存进行调整,不调整或调整成功返回true,调整失败返回false
        /// </summary>
        /// <param name="elementCount">元素个数</param>
        /// <returns>不调整或调整成功返回true,调整失败返回false</returns>
        public bool TryCheck(int elementCount)
        {
            return this.PrimitiveCheck(elementCount);
        }

        /// <summary>
        /// 检查内存大小是否足够.检查过程中根据内存调整模式对内存进行调整,不调整或调整成功返回true,调整失败返回false
        /// </summary>
        /// <param name="elementCount">元素个数</param>
        /// <returns>不调整或调整成功返回true,调整失败返回false</returns>
        public bool TryCheck(long elementCount)
        {
            return this.PrimitiveCheck(elementCount);
        }

        /// <summary>
        /// 检查内存大小是否足够.检查过程中根据内存调整模式对内存进行调整,不调整或调整成功直接,调整失败抛出异常
        /// </summary>
        /// <param name="elementCount">元素个数</param>
        public void Check(int elementCount)
        {
            if (elementCount < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(elementCount), $"元数个数不能小于0,值\"{elementCount}\"无效.");
            }

            if (!this.PrimitiveCheck(elementCount))
            {
                throw new AccessViolationException($"内存指针元素个数从{this._longCapacity}-{elementCount}申请或调整内存失败,错误信息:{this._error}");
            }
        }

        /// <summary>
        /// 检查内存大小是否足够.检查过程中根据内存调整模式对内存进行调整,不调整或调整成功直接,调整失败抛出异常
        /// </summary>
        /// <param name="elementCount">元素个数</param>
        public void Check(long elementCount)
        {
            if (elementCount < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(elementCount), $"元数个数不能小于0,值\"{elementCount}\"无效.");
            }

            if (!this.PrimitiveCheck(elementCount))
            {
                throw new AccessViolationException($"内存指针元素个数从{this._longCapacity}-{elementCount}申请或调整内存失败,错误信息:{this._error}");
            }
        }


        private int _autoCount = 0;
        private bool PrimitiveCheck(long elementCount)
        {
            if (this._memoryType == UnmanagedMemoryType.Fix)
            {
                this._error = "内存大小已固定,不允许调整.";
                return false;
            }

            switch (this._adjustMode)
            {
                case UnmanagedMemoryAdjustMode.Limit:
                    if (elementCount <= this._longCapacity)
                    {
                        //仅当需要的元素个数多于已分配元素个数才调整
                        return true;
                    }
                    break;
                case UnmanagedMemoryAdjustMode.Auto:
                    if (elementCount == this._longCapacity)
                    {
                        this._autoCount = 0;
                        return true;
                    }
                    else if (elementCount < this._longCapacity)
                    {
                        this._autoCount++;

                        if (this._autoCount >= this._maxAutoCount)
                        {
                            //连续100次检查需要的元素数量都少于已分配内存元素数量,则减少内存
                            this._autoCount = 0;
                        }
                        else
                        {
                            return true;
                        }
                    }
                    else
                    {
                        this._autoCount = 0;
                    }
                    break;
                default:
                case UnmanagedMemoryAdjustMode.Always:
                    if (elementCount == this._longCapacity)
                    {
                        //仅当元素数据不同就调整
                        return true;
                    }
                    break;
            }

            if (elementCount <= 0)
            {
                if (this._longCapacity > 0)
                {
                    this.PrimitiveFree();
                }

                this._capacity = 0;
                this._longCapacity = 0L;
                return true;
            }


            long byteLength = elementCount * this._elementSize;

            ////检查主机是否有足够的物理可用
            //if (elementCount > this._longCapacity)
            //{
            //    const ulong _HEAP_MAXREQ_x64 = 0xFFFFFFFFFFFFFFE0;// 17179869184 GB
            //    const ulong _HEAP_MAXREQ_x86 = 0xFFFFFFE0;//4095.999 MB
            //    if (Environment.Is64BitProcess)
            //    {
            //        if ((ulong)byteLength > _HEAP_MAXREQ_x64)
            //        {
            //            this._error = $"需要申请的内存大小{byteLength}Byte超出操作系统堆限制{_HEAP_MAXREQ_x64}";
            //            return false;
            //        }
            //    }
            //    else
            //    {
            //        if ((ulong)byteLength > _HEAP_MAXREQ_x86)
            //        {
            //            this._error = $"需要申请的内存大小{byteLength}Byte超出操作系统堆限制{_HEAP_MAXREQ_x86}";
            //            return false;
            //        }
            //    }

            //    //MemoryInfo memoryInfo = EnvironmentEx.GetHostMemoryInfo();
            //    //if (byteLength > memoryInfo.AvailPhys)
            //    //{
            //    //    this._error = $"操作系统没有足够物理内存可供申请,当前主机可供申请内存为:{memoryInfo.AvailPhys}/{memoryInfo.TotalPhys}Byte,需要申请的内存大小为:{byteLength}Byte";
            //    //    return false;
            //    //}
            //}

            try
            {
                if (this.PrimitiveCheck(byteLength, out this._error))
                {
                    var handler = OnUnmanagedMemoryExtended;
                    if (handler != null)
                    {
                        handler(this, new UnmanagedMemoryExtendedArgs(this._id, this._longCapacity, elementCount));
                    }
                    Interlocked.Add(ref _totalBytes, byteLength);

                    if (elementCount > int.MaxValue)
                    {
                        this._capacity = int.MaxValue;
                    }
                    else
                    {
                        this._capacity = (int)elementCount;
                    }
                    this._longCapacity = elementCount;
                    return true;
                }
                else
                {
                    return false;
                }
            }
            catch (OutOfMemoryException omex)
            {
                this._error = $"{omex.Message},将内存元素个数从{this._capacity}调整为{elementCount}失败.";
                return false;
            }
            catch (AccessViolationException avex)
            {
                this._error = $"{avex.Message},将内存元素个数从{this._capacity}调整为{elementCount}失败.";
                return false;
            }
            catch (Exception ex)
            {
                this._error = $"{ex.Message},将内存元素个数从{this._capacity}调整为{elementCount}失败.";
                return false;
            }
        }

        /// <summary>
        /// 调整指针指向的内存大小,调整成功返回true,调整失败返回false
        /// </summary>
        /// <param name="byteLength">要申请的内存大小字节数</param>
        /// <param name="error">调整失败时的错误信息</param>
        /// <returns>调整成功返回true,调整失败返回false</returns>
        protected abstract bool PrimitiveCheck(long byteLength, out string error);

        /// <summary>
        /// 释放指针
        /// </summary>
        protected abstract void PrimitiveFree();


        /// <summary>
        /// 抛出内存调失败异常
        /// </summary>
        public void ThrowAdjustFailException()
        {
            throw new AccessViolationException(this._error);
        }




        /// <summary>
        /// 清除当前对象数据指针指向的内容。
        /// </summary>
        public void Clear()
        {
            this.PrimitiveClear();
        }

        /// <summary>
        /// 清除当前对象数据指针指向的内容。
        /// </summary>
        protected abstract void PrimitiveClear();




        /// <summary>
        /// 用指定的值填充到当前对象数据指针指向的内容
        /// </summary>
        /// <typeparam name="TValue">值类型</typeparam>
        /// <param name="value"></param>
        public void Fill<TValue>(TValue value) where TValue : struct
        {
            this.PrimitiveFill<TValue>(value);
        }

        /// <summary>
        /// 用指定的值填充到当前对象数据指针指向的内容
        /// </summary>
        /// <typeparam name="TValue">值类型</typeparam>
        /// <param name="value">指定的值</param>
        protected abstract void PrimitiveFill<TValue>(TValue value) where TValue : struct;



        /// <summary>
        /// 重置指针数据长度为0,并将已申请的内存空间中的数据调用Clear方法清空
        /// </summary>
        public void Reset()
        {
            this._length = 0;
            this._longLength = 0;
            this.PrimitiveClear();
        }

        /// <summary>
        /// 重置指针数据长度为0,并将已申请的内存空间全部填充为指定值
        /// </summary>
        /// <typeparam name="TValue"></typeparam>
        /// <param name="value">指定的值</param>
        public void Reset<TValue>(TValue value) where TValue : struct
        {
            this._length = 0;
            this._longLength = 0;
            this.PrimitiveFill(value);
        }


        /// <summary>
        /// 释放内存资源
        /// </summary>
        public void Dispose()
        {
            if (this._memoryType == UnmanagedMemoryType.Revisable)
            {
                long byteLength = 0 - this._longCapacity * this._elementSize;
                Interlocked.Decrement(ref _total);
                Interlocked.Add(ref _totalBytes, byteLength);

                this.PrimitiveFree();
                this.Dispose(true);
                this._capacity = 0;
                this._longCapacity = 0;
                GC.SuppressFinalize(this);
            }
        }

        /// <summary>
        /// 释放内存资源
        /// </summary>
        /// <param name="disposing">标识</param>
        protected virtual void Dispose(bool disposing)
        {

        }

    }





    /// <summary>
    /// 非托管内存指针接口
    /// </summary>
    public interface IUnmanagedMemoryPointer : IDisposable
    {
        /// <summary>
        /// 内存标识ID
        /// </summary>
        long ID { get; }

        /// <summary>
        /// 内存类型
        /// </summary>
        UnmanagedMemoryType MemoryType { get; }

        /// <summary>
        /// 非托管内存调整模式
        /// </summary>
        UnmanagedMemoryAdjustMode AdjustMode { get; set; }

        /// <summary>
        /// 元素大小
        /// </summary>
        int ElementSize { get; }

        /// <summary>
        /// 指针对应类型结构的元素最大个数
        /// </summary>
        int Capacity { get; }

        /// <summary>
        /// 指针类型结构对应的元素个数
        /// </summary>
        long LongCapacity { get; }

        /// <summary>
        /// 有效数据元素个数
        /// </summary>
        int Length { get; set; }

        /// <summary>
        /// 有效数据元素个数
        /// </summary>
        long LongLength { get; set; }

        /// <summary>
        /// 获取或设置最大自动调整计数次数,默认100
        /// </summary>
        int MaxAutoCount { get; set; }

        /// <summary>
        /// 获取检查内存失败时的错误信息
        /// </summary>
        string Error { get; }



        /// <summary>
        /// 检查内存大小是否足够.
        /// 检查过程中根据内存调整模式对内存进行调整,不调整或调整成功正常则设置数据长度为调整长度,操作成功失败抛出异常
        /// </summary>
        /// <param name="elementCount">需要的元素个数</param>
        void CheckSetLength(int elementCount);

        /// <summary>
        /// 检查内存大小是否足够.
        /// 检查过程中根据内存调整模式对内存进行调整,不调整或调整成功正常则设置数据长度为调整长度,操作成功失败抛出异常
        /// </summary>
        /// <param name="elementCount">需要的元素个数</param>
        void CheckSetLength(long elementCount);

        /// <summary>
        /// 尝试检查内存大小是否足够.如果不够则内存进行调整,不调整或调整成功正常则设置数据长度为调整长度,操作成功返回true,失败返回false
        /// </summary>
        /// <param name="elementCount">需要的元素个数</param>
        /// <returns>成功返回true,失败返回false</returns>
        bool TryCheckSetLength(int elementCount);

        /// <summary>
        /// 尝试检查内存大小是否足够.如果不够则内存进行调整,不调整或调整成功正常则设置数据长度为调整长度,操作成功返回true,失败返回false
        /// </summary>
        /// <param name="elementCount">需要的元素个数</param>
        /// <returns>成功返回true,失败返回false</returns>
        bool TryCheckSetLength(long elementCount);




        /// <summary>
        /// 检查内存大小是否足够.检查过程中根据内存调整模式对内存进行调整,不调整或调整成功返回true,调整失败返回false
        /// </summary>
        /// <param name="elementCount">元素个数</param>
        /// <returns>不调整或调整成功返回true,调整失败返回false</returns>
        bool TryCheck(int elementCount);

        /// <summary>
        /// 检查内存大小是否足够.检查过程中根据内存调整模式对内存进行调整,不调整或调整成功返回true,调整失败返回false
        /// </summary>
        /// <param name="elementCount">元素个数</param>
        /// <returns>不调整或调整成功返回true,调整失败返回false</returns>
        bool TryCheck(long elementCount);

        /// <summary>
        /// 检查内存大小是否足够.检查过程中根据内存调整模式对内存进行调整,不调整或调整成功直接,调整失败抛出异常
        /// </summary>
        /// <param name="elementCount">元素个数</param>
        void Check(int elementCount);

        /// <summary>
        /// 检查内存大小是否足够.检查过程中根据内存调整模式对内存进行调整,不调整或调整成功直接,调整失败抛出异常
        /// </summary>
        /// <param name="elementCount">元素个数</param>
        void Check(long elementCount);





        /// <summary>
        /// 抛出内存调失败异常
        /// </summary>
        void ThrowAdjustFailException();

        /// <summary>
        /// 清除当前对象数据指针指向的内容。
        /// </summary>
        void Clear();

        /// <summary>
        /// 用指定的值填充到当前对象数据指针指向的内容
        /// </summary>
        /// <typeparam name="TValue">值类型</typeparam>
        /// <param name="value"></param>
        void Fill<TValue>(TValue value) where TValue : struct;
    }

    /// <summary>
    /// 非托管内存调整模式
    /// </summary>
    public enum UnmanagedMemoryAdjustMode
    {
        /// <summary>
        /// 当检查的元素数量与已分配元素数量不同就调整
        /// </summary>
        Always = 1,

        /// <summary>
        /// 仅当新的元素数量超过已有元素数量时才调整
        /// </summary>
        Limit = 2,

        /// <summary>
        /// 根据参数参数自检调整
        /// </summary>
        Auto = 3,
    }

    /// <summary>
    /// 非托管内存类型
    /// </summary>
    public enum UnmanagedMemoryType
    {
        /// <summary>
        /// 地址和大小皆固定的内存,不允许调整
        /// </summary>
        Fix,

        /// <summary>
        /// 可通过realloc调整的
        /// </summary>
        Revisable

    }

    /// <summary>
    /// 非托管内存扩展事件参数
    /// </summary>
    public class UnmanagedMemoryExtendedArgs : EventArgs
    {
        /// <summary>
        /// 内存标识ID
        /// </summary>
        public long ID { get; private set; }

        /// <summary>
        /// 扩展前内存容量
        /// </summary>
        public long OldCapacity { get; }

        /// <summary>
        /// 扩展后内存容量
        /// </summary>
        public long NewCapacity { get; }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="id">内存标识ID</param>
        /// <param name="oldCapacity">扩展前内存容量</param>
        /// <param name="newCapacity">扩展后内存容量</param>
        public UnmanagedMemoryExtendedArgs(long id, long oldCapacity, long newCapacity)
        {
            this.ID = id;
            this.OldCapacity = oldCapacity;
            this.NewCapacity = newCapacity;
        }

    }
}
